import bean.AddIcon;
import bean.FileInfo;
import bean.Message;
import core.db.DbHelper;
import core.db.util.LogUtils;
import core.db.util.TextUtils;
import core.generatingcode.GeneratingJava;
import core.swagger.AnalysisSwagger;
import core.task.Task;
import core.task.async.bean.Result;
import core.task.async.callback.Callback;
import core.task.async.callback.IWorker;
import core.task.async.worker.ResultState;
import core.task.async.worker.WorkResult;
import doinbackground.AnalysisSwaggerTask;
import doinbackground.BrowserTask;
import doinbackground.GeneratingJavaTask;
import doinbackground.InitDbTask;
import entity.History;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.BrowserFunction;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.ibex.nestedvm.util.Seekable;
import service.ProcessService;
import util.CheckFileConsistency;
import util.ImageUtil;
import util.MD5;
import util.ZipUtil;
import util.json.JsonMananger;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.Map;

public class BrowserHelper extends BrowserFunction {

    public static String resRoot;
    private boolean isCompleted = false;
    public BrowserHelper(Browser browser, String name) {
        super(browser, name);
        resRoot = this.getClass().getResource("/res/").getPath().substring(1);
        String rootPath = resRoot+"index.html";
        browser.setUrl(rootPath);
        browser.addProgressListener(new ProgressListener() {
            @Override
            public void changed(ProgressEvent progressEvent) {

            }

            @Override
            public void completed(ProgressEvent progressEvent) {
                isCompleted = true;
                callback("onReady","onReady");
            }
        });
        init();
    }
    //配置信息
    public static Map<String,String> config;

    /**
     * 初始化
     */
    private void init(){
        Task.exec(InitDbTask.class).addParam(resRoot).callback(new Callback() {
            @Override
            public void result(boolean success, WorkResult<Result> result) {
                if(success){
                    config = result.getResult().get();
                }
            }
        }).start();
    }

    @Override
    public Object function(Object[] arguments) {
        if(arguments.length>=2){
            call(arguments[0].toString(),arguments[1]);
        }
        return super.function(arguments);
    }

    /**
     * 调用方法
     * @param method
     * @param data
     */
    private void call(String method,Object data){
        switch (method){
            case "openSourcePath":
                try {
                    Desktop.getDesktop().open(new File(resRoot+"server/actions/"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            case "openFile":
                FileDialog fd=new FileDialog(Main.shell, SWT.OPEN);
                History history = DbHelper.findById(History.class,MD5.encrypt(method));
                if(history!=null){
                    fd.setFilterPath(history.getValue());
                }else{
                    fd.setFilterPath(System.getProperty("user.dir"));
                }
                fd.setFilterExtensions(new String[]{"*.saz"});
                fd.setFilterNames(new String[]{"Fiddler Session Archive(*.saz)"});
                String file=fd.open();
                if(file!=null){
                    errorBack(method,0,"正在解析数据...");
                    history = new History();
                    history.setId(MD5.encrypt(method));
                    history.setKey(method);
                    File file1 = new File(file);
                    history.setValue(file1.getParent().replaceAll("\\\\","/"));
                    DbHelper.saveOrUpdate(history);
                    call("analysisFiddler",file);
                }
                break;
            case "fileSign":
                FileDialog fileSign=new FileDialog(Main.shell, SWT.OPEN);
                History fileSignHistory = DbHelper.findById(History.class,MD5.encrypt(method));
                if(fileSignHistory!=null){
                    fileSign.setFilterPath(fileSignHistory.getValue());
                }else{
                    fileSign.setFilterPath(System.getProperty("user.dir"));
                }
                fileSign.setFilterExtensions(new String[]{"*.apk"});
                fileSign.setFilterNames(new String[]{"安卓应用(*.apk)"});
                String fileSignPath=fileSign.open();
                if(fileSignPath!=null){
                    File f = new File(fileSignPath);
                    if(f.exists()){
                        try {
                            String sign = CheckFileConsistency.getFileMD5String(f);
                            successBack(method,sign);
                            fileSignHistory = new History();
                            fileSignHistory.setId(MD5.encrypt(method));
                            fileSignHistory.setKey(method);
                            fileSignHistory.setValue(f.getParent().replaceAll("\\\\","/"));
                            DbHelper.saveOrUpdate(fileSignHistory);
                            return;
                        } catch (IOException e) {
                            e.printStackTrace();
                            errorBack(method,0,"文件签名失败！");
                            return;
                        }
                    }
                }
                errorBack(method,0,"请选择文件...");
                break;
            case "addIcon":
                if(data==null){
                    errorBack(method,400,"参数为空!");
                    return;
                }
                AddIcon addIcon = JsonMananger.jsonToBean(data.toString(),AddIcon.class);
                //可多选
                FileDialog addIconDialog=new FileDialog(Main.shell, SWT.OPEN|SWT.MULTI);
                History addIconHistory = DbHelper.findById(History.class,MD5.encrypt(method));
                if(addIconHistory!=null){
                    addIconDialog.setFilterPath(addIconHistory.getValue());
                }else{
                    addIconDialog.setFilterPath(System.getProperty("user.dir"));
                }
                addIconDialog.setFilterExtensions(new String[]{"*.png"});
                addIconDialog.setFilterNames(new String[]{"PNG图片[大于200*200像素](*.png)"});
                String iconFile = addIconDialog.open();
                if(ProcessService.fileInfo==null){
                    errorBack(method,0,"android studio 未打开项目");
                    return;
                }

                if(iconFile==null){
                    errorBack(method,0,"未选择文件...");
                    return;
                }
                File icFile = new File(iconFile);
                String [] iconList=addIconDialog.getFileNames();//这里是获取文件文件的名字 字符数组

                String parent = icFile.getParent().replaceAll("\\\\","/");;
                int i = 1 ;
                String filename = addIcon.getFilename();
                String result = "";
                for(String addIconPath:iconList){
                        File f = new File(parent+"/"+addIconPath);
                        if(f.exists()){
                            try {
                                if(!ImageUtil.check(f)){
                                    result+="图片"+i+"长宽需大于200像素;";
                                    continue;
                                }
                                if(!TextUtils.isEmpty(filename)&&iconFile.length()>1){
                                    addIcon.setFilename(filename+i);
                                }
                                boolean success = ImageUtil.zoomImages(f,ProcessService.fileInfo.getModelPath(),addIcon);
                                if(success){
                                    result+="图片"+i+"添加成功;";
                                }else{
                                    result+="图片"+i+"添加失败;";
                                }
                            } catch (IOException e) {
                                result+="图片"+i+"裁剪失败,请重试!错误信息:"+e.getMessage()+";";
                            }
                    }
                    i++;
                }
                if(parent!=null) {
                    addIconHistory = new History();
                    addIconHistory.setId(MD5.encrypt(method));
                    addIconHistory.setKey(method);
                    addIconHistory.setValue(parent);
                    DbHelper.saveOrUpdate(addIconHistory);
                }
                successBack(method,result);
              break;
            case "analysisSwagger":
                    AnalysisSwaggerTask analysisSwaggerTask = new AnalysisSwaggerTask();
                    analysisSwaggerTask.setOnCallback(new AnalysisSwagger.OnCallback() {
                        @Override
                        public void onProgress(int position, int max, String msg) {
                            errorBack(method,1,msg);
                        }

                        @Override
                        public void onSuccess(String msg) {
                            successBack(method,msg);
                        }

                        @Override
                        public void onError(String msg) {
                            errorBack(method,0,msg);
                        }
                    });
                    exec(analysisSwaggerTask,method,data);
                    break;
            case "generateCode":
                GeneratingJavaTask generatingJavaTask = new GeneratingJavaTask();
                generatingJavaTask.setOnCallback(new GeneratingJava.OnCallback() {
                    @Override
                    public void onProgress(int position, int size, String msg) {
                        errorBack(method,1,msg);
                    }

                    @Override
                    public void onSuccess(String msg) {
                        successBack(method,msg);
                    }

                    @Override
                    public void onError(String msg) {
                        errorBack(method,0,msg);
                    }
                });
                exec(generatingJavaTask,method,data);
                break;
                default:
                    exec(BrowserTask.class,method,data);
                    break;

        }
    }

    /**
     * 执行异步任务
     * @param obj
     * @param method
     * @param data
     */
    private void exec(Object obj,String method,Object data){
        Task.exec(obj).addParam(method)
                .addParam("data",data)
                .addParam("resRoot",resRoot)
                .callback(new Callback() {
                    @Override
                    public void result(boolean success, WorkResult<Result> result) {
                        if(result==null){
                            return;
                        }
                        String key = result.getResult().get();
                        if(key==null){
                            return;
                        }
                        if(success){
                            String data = result.getResult().get("result");
                            callback(key,data);
                        }else{
                            if(result.getResultState()== ResultState.TIMEOUT){
                                errorBack(key,408,"执行超时!");
                            }else if(result.getResultState()==ResultState.EXCEPTION){
                                errorBack(key,503, "执行出错:"+result.getEx().getMessage());
                            }else{
                                errorBack(key,400,"发生未知错误");
                            }
                        }
                    }
                }).start();
    }

    /**
     *  回调
     * @param method
     * @param json
     */
    private void callback(String method,String json){
        if(isCompleted){
            try {
                Display.getDefault().asyncExec(new Runnable() {
                    @Override
                    public void run() {
                       boolean b = getBrowser().execute( "callback('"+method+"','"+json+"');");
                       if(!b){
                           LogUtils.e(method+"->回调失败。");
                       }
                    }
                });
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 成功
     * @param method
     * @param msg
     */
    private void successBack(String method,String msg){
        errorBack(method,200,msg);
    }
    /**
     *  出错
     * @param method
     * @param code
     * @param msg
     */
    private void errorBack(String method,int code,String msg){
        Message message = new Message();
        message.setCode(code);
        if(code==200){
            message.setData(msg);
        }else{
            message.setMessage(msg);
        }
        callback(method, JsonMananger.beanToJsonStr(message));
    }

}
